#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "CRC16.h"
#include <QList>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent),
      ui(new Ui::MainWindow),
      spThread_(this),
      spWorker_()
{
    ui->setupUi(this);
    /// TODO:自动找设备
    ui->btnConnectAuto->hide();

    ioBtnArr_[0] = ui->btnPower;
    ioBtnArr_[1] = ui->btnIO1;
    ioBtnArr_[2] = ui->btnIO2;

    /// 1.拉起后台串口通信线程
    spWorker_.moveToThread(&spThread_);
    spThread_.start();

    /// 获取串口列表并放到comboBox
    QList<QSerialPortInfo> serialPorts = QSerialPortInfo::availablePorts();
    // 遍历串口列表，将串口名字添加到ComboBox中
    foreach (const QSerialPortInfo &serialPortInfo, serialPorts) {
        ui->comboBox->addItem(serialPortInfo.portName());
    }
    if (!serialPorts.empty()) {
        ui->comboBox->setCurrentIndex(serialPorts.size() - 1);
    }

    /// 3.
    connect(this, &MainWindow::notifyConnectSP, &spWorker_, &SpWorker::onNotifyConnectSP);
    connect(this, &MainWindow::notifySend, &spWorker_, &SpWorker::onNotifySend);
}

MainWindow::~MainWindow()
{
//    emit notifyExit();
//    spThread_.wait();
    spThread_.terminate();
    delete ui;
}


void MainWindow::on_btnPower_clicked()
{
    if (this->io_ & 0x01u) {
        /// 若第0bit为1, 则此处为关闭
        this->io_ = (io_ & (~0x01u)) & 0x07u;
    } else {
        this->io_ = (io_ | 0x01u) & 0x07u;
    }
    updateIOBtn();
}

void MainWindow::on_btnIO1_clicked()
{
    if (this->io_ & 0x02u) {
        /// 若第0bit为1, 则此处为关闭
        this->io_ = (io_ & (~0x02u)) & 0x07u;
    } else {
        this->io_ = (io_ | 0x02u) & 0x07u;
    }
    updateIOBtn();
}

void MainWindow::on_btnIO2_clicked()
{
    if (this->io_ & 0x04u) {
        /// 若第0bit为1, 则此处为关闭
        this->io_ = (io_ & (~0x04u)) & 0x07u;
    } else {
        this->io_ = (io_ | 0x04u) & 0x07u;
    }
    updateIOBtn();
}

void MainWindow::on_btnConnect_clicked()
{
    if (spWorker_.isSpConnected() == false) {
        QString selectedPort = ui->comboBox->currentText();
        emit notifyConnectSP(selectedPort);
        QThread::msleep(250);
        if (spWorker_.isSpConnected()) {
            /// 使不可用
            ui->btnConnect->setText("已连接");
            ui->btnConnect->setDisabled(true);
            ui->btnConnect->setStyleSheet("background-color: rgb(0,85,0);"
                                          "border-radius: 6px;"
                                          "color:rgb(212, 212, 212);");

            ui->btnConnectAuto->setDisabled(true);
            ui->btnConnectAuto->setStyleSheet("color:rgb(212, 212, 212);");

            /// 刷新IO按钮
            updateIOBtn();
        } else {
            QMessageBox::information(this, "提示", "串口连接不成功");
        }
    }
}

void MainWindow::on_btnConnectAuto_clicked()
{

}

void MainWindow::switchOnBtn(int i)
{
    if (ioBtnArr_[i]) {
        ioBtnArr_[i]->setText("闭合");
        ioBtnArr_[i]->setStyleSheet("border-radius:10px;" \
                                    "color:rgb(255, 255, 255);" \
                                    "background-color: rgb(0, 85, 0);");
    }
}

void MainWindow::switchOffBtn(int i)
{
    if (ioBtnArr_[i]) {
        ioBtnArr_[i]->setText("断开");
        ioBtnArr_[i]->setStyleSheet("border-radius:10px;" \
                                    "color:rgb(255, 255, 255);" \
                                    "background-color: rgb(185, 0, 0);");
    }
}

void MainWindow::updateIOBtn()
{
    int k = 0x01;
    for (int i = 0; i < 3; ++i, k <<= 1) {
        if (io_ & k) {
            switchOnBtn(i);
        } else {
            switchOffBtn(i);
        }
    }

    /// 2.发送指令
//    01 05 00 06 00 03 6D CA
//    01 05 00 06 00 01 EC 0B √
//    01 05 00 06 00 00 2D CB √
    QByteArray buf(8, '\0');
    buf[0] = 0x01;
    buf[1] = 0x05;
    buf[2] = 0x00;
    buf[3] = 0x06;
    buf[4] = 0x00;
    buf[5] = this->io_;
    uint16_t crc = calcCRC16(static_cast<char*>(buf.data()), 6);
    buf[6] = (crc >> 8) & 0xFF;
    buf[7] = crc & 0xFF;
    qDebug() << buf.toHex();
    spWorker_.setTxBuffer(buf);
    emit notifySend();
}
